#!/usr/bin/env node
/* eslint-env node */

const child = require('child_process')
const path = require('path')

const fs = require('fs-extra')

async function run() {
  const version = process.argv[2].replace(/v/, '')

  if (!version) {
    console.error(
      'You have to provide a version.\nUsage ./update-package-versions <version>',
    )
    process.exitCode = 1
    return
  }

  const cwd = path.join(__dirname, '../')

  const cmd = [
    'yarn lerna version',
    version,
    '--force-publish',
    '--no-push',
    '--no-git-tag-version',
    '--exact',
    '--yes',
  ].join(' ')

  console.log(`Running "${cmd}"`)
  console.log()
  child.execSync(cmd, {
    cwd,
  })
  console.log()

  // Updates create-redwood-app template
  console.log('Updating CRWA template...')
  const tsTemplatePath = path.join(
    cwd,
    'packages/create-redwood-app/templates/ts',
  )
  updateRWJSPkgsVersion(tsTemplatePath, version)
  updateRWJSPkgsVersion(path.join(tsTemplatePath, 'api'), version)
  updateRWJSPkgsVersion(path.join(tsTemplatePath, 'web'), version)
  console.log()

  const jsTemplatePath = path.join(
    cwd,
    'packages/create-redwood-app/templates/js',
  )
  updateRWJSPkgsVersion(jsTemplatePath, version)
  updateRWJSPkgsVersion(path.join(jsTemplatePath, 'api'), version)
  updateRWJSPkgsVersion(path.join(jsTemplatePath, 'web'), version)
  console.log()

  // Updates __fixtures__/test-project packages
  console.log('Updating test-project fixture...')
  const fixturePath = path.join(cwd, '__fixtures__/test-project')
  updateRWJSPkgsVersion(fixturePath, version)
  updateRWJSPkgsVersion(path.join(fixturePath, 'api'), version)
  updateRWJSPkgsVersion(path.join(fixturePath, 'web'), version)
  console.log()
}

/**
 * Iterates over `@redwoodjs/*` dependencies in a package.json and updates their version.
 *
 * @param {string} pkgPath
 * @param {string} version
 */
function updateRWJSPkgsVersion(pkgPath, version) {
  const pkg = fs.readJSONSync(path.join(pkgPath, 'package.json'), 'utf-8')

  for (const dep of Object.keys(pkg.dependencies ?? {}).filter(isRWJSPkg)) {
    console.log(` - ${dep}: ${pkg.dependencies[dep]} => ${version}`)
    pkg.dependencies[dep] = `${version}`
  }

  for (const dep of Object.keys(pkg.devDependencies ?? {}).filter(isRWJSPkg)) {
    console.log(` - ${dep}: ${pkg.devDependencies[dep]} => ${version}`)
    pkg.devDependencies[dep] = `${version}`
  }

  fs.writeJSONSync(path.join(pkgPath, 'package.json'), pkg, { spaces: 2 })
}

const isRWJSPkg = (pkg) => pkg.startsWith('@redwoodjs/')

run()
